package com.whims.replaceFinalizer;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 替换终结器
 */
public class CleanupFinalizer extends WeakReference {

    private static ReferenceQueue< CleanupFinalizer > finRefQueue;
    private static HashSet< CleanupFinalizer > pendingRefs = new HashSet < >();
    private boolean closed = false;
    public CleanupFinalizer(Object o) {
        super(o,finRefQueue);
        allocateNative();
        pendingRefs.add(this);
    }
    public void setClosed() {
        closed = true;
        doNativeCleanup();
    }
    public void cleanup() {
        if (!closed) {
            doNativeCleanup();
        }
    }
    private native void allocateNative();
    private native void doNativeCleanup();

    static {
        finRefQueue = new ReferenceQueue < >();
        Runnable r = new Runnable() {
            public void run() {
                CleanupFinalizer fr;
                while (true) {
                    try {
                        fr = (CleanupFinalizer) finRefQueue.remove();
                        fr.cleanup();
                        pendingRefs.remove(fr);
                    } catch(Exception ex) {
                        Logger.getLogger(CleanupFinalizer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };
        Thread t = new Thread(r);
        t.setDaemon(true);
        t.start();
    }
}
